package com.hipmarket.platform.security.config

import com.fasterxml.jackson.databind.ObjectMapper
import com.hipmarket.platform.security.JwtAuthenticationUser
import com.hipmarket.platform.security.exception.IllegalConvertException
import org.springframework.core.MethodParameter
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.web.bind.support.WebDataBinderFactory
import org.springframework.web.context.request.NativeWebRequest
import org.springframework.web.method.support.ModelAndViewContainer
import org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver

class JwtAuthenticationMethodArgumentResolver: AbstractMessageConverterMethodArgumentResolver {

    constructor(converters: List<HttpMessageConverter<*>>): super(converters)

    constructor(converters: List<HttpMessageConverter<*>>, advice: List<Any>?): super(converters, advice)

    private val objectMapper = ObjectMapper()

    override fun supportsParameter(parameter: MethodParameter): Boolean {
        return parameter.parameterType.isAssignableFrom(JwtAuthenticationUser::class.java)
    }

    override fun resolveArgument(p0: MethodParameter, p1: ModelAndViewContainer?, p2: NativeWebRequest, p3: WebDataBinderFactory?): Any? {
        val parameter = p0.nestedIfOptional()
        val parameterType = parameter.parameterType
        val authentication = jwtAuthenticationUser()
        return objectMapper.convertValue(authentication, parameterType)
    }


    fun jwtAuthenticationUser(): JwtAuthenticationUser {
        val authentication = SecurityContextHolder.getContext().authentication
        if (authentication is JwtAuthenticationUser) {
            return authentication
        }
        throw IllegalConvertException()
    }

}